package org.example.utils;

import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.Numberings;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import com.aspose.words.Document;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordUtils {
    /*
     * @Description:
     * @Param:
     * @param inputPath word文件路径
     * @param keysToCheck 需要校验的键
     * @return:
     **/
    public static void checkKeys(String inputPath, Set<String> keysToCheck) {
        XWPFDocument document;
        try (FileInputStream fis = new FileInputStream(inputPath)) {
            document = new XWPFDocument(fis);
        } catch (IOException e) {
            throw new RuntimeException("读取模板文件失败: " + e.getMessage());
        }
        // 查找模板中的所有占位符
        Set<String> placeholders = findPlaceholders(document);
        // 校验模板中是否包含所有替换变量！
        for (String key : keysToCheck) {
            if (!placeholders.contains(key)) {
                throw new RuntimeException("缺少模板占位符对应的替换内容: " + key);
            }
        }
    }
    /*
     * @Description: 插入word
     * @param inputPath 输入文件路径
     * @param outputPath 输出文件路径
     * @param hashMap 替换内容
     * @param keysToCheck 需要校验的键
    **/
    public static void insertWord(String inputPath, String outputPath, HashMap<String, Object> hashMap) {
        // 使用poi-tl模板引擎进行渲染
        XWPFTemplate template = XWPFTemplate.compile(inputPath).render(hashMap);
        try {
            // 将渲染后的模板写入输出文件
            template.writeAndClose(Files.newOutputStream(Paths.get(outputPath)));
        } catch (IOException e) {
            // 捕获异常并抛出运行时异常
            throw new RuntimeException("写入输出文件失败: " + e.getMessage());
        }
    }

    /*
     * @Description: word转pdf
     * @Param:
     * @param wordFilePath word文件路径
     * @param pdfFilePath  pdf文件路径
     * @return:
    **/
    public static void wordToPdf(String wordFilePath, String pdfFilePath) {
        FileOutputStream fileOS = null;
        try {
            Document doc = new Document(wordFilePath);
            fileOS = new FileOutputStream(new File(pdfFilePath));
            // 保存转换的pdf文件
            doc.save(fileOS, SaveFormat.PDF);
        } catch (Exception e) {
            throw new RuntimeException("转换Word文档为PDF失败: " + e.getMessage());
        } finally {
            try {
                if (fileOS != null) {
                    fileOS.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("关闭文件输出流时发生错误");
            }
        }
    }


    /*
     * @Description: 查找word中的所有占位符
     * @param document
     * @return java.util.Set<java.lang.String>
    **/
    private static Set<String> findPlaceholders(XWPFDocument document) {
        Set<String> placeholders = new HashSet<>();
        Pattern pattern = Pattern.compile("\\{\\{\\s*(@?\\w+)\\s*\\}\\}");
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            String paragraphText = paragraph.getText();
            Matcher matcher = pattern.matcher(paragraphText);
            while (matcher.find()) {
                placeholders.add(matcher.group(1).trim());
            }
        }
        return placeholders;
    }

    public static void main(String[] args) {
        // 定义输入和输出文件的路径
        String inputPath = "D:\\software\\Java\\projects\\word-utils\\src\\main\\java\\org\\example\\utils\\demo.docx";
        String outputPath = "D:\\software\\Java\\projects\\word-utils\\src\\main\\java\\org\\example\\utils\\output.docx";
        String outputPdfPath = "D:\\software\\Java\\projects\\word-utils\\src\\main\\java\\org\\example\\utils\\output.pdf";
        // 定义替换内容的键值对
        HashMap<String, Object> hashMap = new HashMap<>();
        // 承租方
        hashMap.put("name", "Hi, poi-tl Word模板引擎");
        // 房屋基本情况
        hashMap.put("list", "2层1户、"+"2层2户、"+"2层3户");
        // 租约起止日期
        hashMap.put("zuFromToDate", "2022年一月一日至2023年一月一日");
        // 押金
        hashMap.put("zj", "5000");
        // 押金大写
        hashMap.put("dxzj", "伍佰");
        // 押金
        hashMap.put("yj", "500");
        // 约定租金
        hashMap.put("ydzj", "500");
        // 调用insertWord方法来处理文档
        HashSet<String> strings = new HashSet<>();
        strings.add("yz1");
        checkKeys(inputPath, strings);
        insertWord(inputPath, outputPath, hashMap);
        // 将Word文档转换为PDF
        wordToPdf(outputPath, outputPdfPath);
    }
}
